
/* boris*/
#include "libBigNum.h"


//Unary negation operator//
big_number big_number:: operator -()
 {
	 big_number temp;
	 temp=*this;
	 temp._sign=((*this)._sign==false);
     return temp;
 }

big_number big_number::operator -(const big_number &param) const
{
     big_number temp;
	if (this->_sign!=param._sign)
	{
		temp=ADD(*this,param);
		temp._sign=_sign;
		return temp;
	}
	else
	{
		if(ABS(*this)>ABS(param))//comparaison function operator ">"
		{
			temp=temp.SUB(*this,param);
			temp._sign=_sign;
			return temp;
		}
		else
		{		    
			temp=temp.SUB(param,*this);
			temp._sign=!param._sign;	
		    return temp;				
		}
	
	}

}

big_number big_number::SUB(const big_number &x,const big_number &y) const
{
    int flag=1,change_flag_fract=0,change_flag_int=1;// lights up if there is a change in array size//
	unsigned long * help_arr,*help_arr1;
	unsigned long carry=0;
	int i,j;
	unsigned short frac,total, tikun_index_x,tikun_index_y,f_zeroes_int=0,f_zeroes_frac=0;
	unsigned short n_int, n_int_y,n_fract;
	
	big_number temp;	
    if(x._fractionalPart>y._fractionalPart)     // max {x,y}<-fraction part of number
       frac=temp._fractionalPart=x._fractionalPart; 
    else 
       frac=temp._fractionalPart=y._fractionalPart;
   total=temp._arr_size= temp._fractionalPart+(x._arr_size-x._fractionalPart);// x is a bigger number : his integer part is bigger/equal than the y's one.
  

   help_arr=(unsigned long*) malloc( total*sizeof(unsigned long));  // carih tikun allocation array size temp._arr_size long number
	if ( help_arr == NULL)
		throw exception(); //TODO def execption can't allocate memory


   n_int=temp._arr_size-temp._fractionalPart;
   n_fract=temp._fractionalPart;
   tikun_index_x=0;                                                                 //upgrade index for x.num_arr
   tikun_index_y=(temp._arr_size-temp._fractionalPart)-(y._arr_size-y._fractionalPart);//upgrade index for y.num_arr: temp's size integer - y's size integer
   temp._fractionalPart=0;
   temp._arr_size=0;
   n_int_y=y._arr_size-y._fractionalPart;
   
   for(i=n_int+n_fract-1;i>=n_int;i--)
	{
		if(x._fractionalPart>=n_fract&&y._fractionalPart>=n_fract)
		{
			if(x._num_array[i-tikun_index_x]>=y._num_array[i-tikun_index_y]+carry)
				{
				 help_arr[i]=x._num_array[i-tikun_index_x]-y._num_array[i-tikun_index_y]-carry;
				 carry=0;
				}
			 else//x._num_array[i] <  y._num_array+carry
			    {
			     help_arr[i]=x._num_array[i-tikun_index_x]+1000000000-(y._num_array[i-tikun_index_y]+carry);
			     carry=1;		   
			    }			
		}
		else if (x._fractionalPart>=n_fract)//temp._fractionalPart)
			   {
			   	help_arr[i]=x._num_array[i-tikun_index_x]-carry;
				carry=0;
			   }
	    else
			   {
				help_arr[i]=1000000000-y._num_array[i-tikun_index_y]-carry;	
				carry=1;
			   }
		n_fract--;

		if( n_fract &&help_arr[i]==0&&flag==1)            //deleting zeroes from end of fraction part
		       change_flag_fract=1;                       // - counting fault zeroes cells in result array's fraction part
	    else
		     {
			   temp._fractionalPart++;                    //unnecessary array's cell
			   temp._arr_size++;
		       flag=0;
			 }
		   
    }//end for
	
	for (;i>=0;i--)// for integer part
		{
          if(n_int_y>0)
		  {
			if(x._num_array[i-tikun_index_x]>=y._num_array[i-tikun_index_y]+carry)
				{
				 help_arr[i]=x._num_array[i-tikun_index_x]-y._num_array[i-tikun_index_y]-carry;
				 carry=0;
				}//end if
		    else                                     //x._num_array[i] <  y._num_array+carry
			   {
			   help_arr[i]=x._num_array[i-tikun_index_x]+1000000000-(y._num_array[i-tikun_index_y]+carry);
			   carry=1;		   
			   }//end else	
			n_int_y--;                                  //number of cells in y's integer part for use to calculate has been down 
		  }
		  else                                          //y._arr_size-y._fractionalPart < n_int
			    {
                 if(x._num_array[i-tikun_index_x]>=carry)
				  {
				    help_arr[i]=x._num_array[i-tikun_index_x]-carry;
				    carry=0;
				  }
			     else                                      //x._num_array[i] <  y._num_array+carry
			      {
			       help_arr[i]=x._num_array[i-tikun_index_x]+1000000000-carry;
			       carry=1;		   
			      }//end else	
	        	}//end else
		  temp._arr_size++;		                           
	  }
	j=0;
		while(j<n_int-1)                                  //deleting of zeroes in integer part
    	 {
			 if(help_arr[j]==0 && change_flag_int==1)
			   { 
				temp._arr_size--;
			    f_zeroes_int++;                           // fault_zeroes in integer part of result
			   }
	         else
		       change_flag_int=0;
			 j++;                                          //value of 'j' point to 
	     }
		if(change_flag_int||change_flag_fract)
		 {
		
			help_arr1=(unsigned long*) malloc( temp._arr_size*sizeof(unsigned long));  // carih tikun allocation array size temp._arr_size long number
			if ( help_arr1 == NULL)
				throw exception(); //TODO def execption can't allocate memory
			for(i=f_zeroes_int,j=0;j<temp._arr_size;i++,j++)
			     help_arr1[j]=help_arr[i];
		   free(temp._num_array);
		   temp._num_array = (unsigned long*) malloc( temp._arr_size*sizeof(unsigned long));		
		   if ( temp._num_array == NULL)
		       throw exception(); //TODO def execption can't allocate memory
	    	memcpy(temp._num_array, help_arr1, temp._arr_size*sizeof(unsigned long));
		    free(help_arr1);
		    free(help_arr);
		    return temp;
		 }
		free(temp._num_array);
	    temp._num_array = (unsigned long*) malloc( temp._arr_size*sizeof(unsigned long));

	    if ( temp._num_array == NULL)
		    throw exception(); //TODO def execption can't allocate memory
	
		memcpy(temp._num_array, help_arr, temp._arr_size*sizeof(unsigned long));
		free(help_arr);
		return temp;
}

big_number big_number::operator - (big_integer & param)
{
	big_number temp;
	temp=(*this)-param.toBigNumber();
	return temp;
}
